package tasknow.testdriver;

import static org.junit.Assert.assertEquals;

import java.util.Calendar;

import org.junit.Test;

import tasknow.commandlogic.CommandLogic;
import tasknow.commandlogic.Logic;
import tasknow.utils.Constants;

public class TestDriver {

	// @author A0096638M

	// Clear is done at the start to ensure the taskVector is empty before
	// testing

	@Test
	public void basicTest1() {
		// Simple functions
		// CRUD
		// Normal test cases within the boundaries

		Calendar temp = Calendar.getInstance();
		temp.add(Calendar.DATE, Constants.DAYS_IN_ONE_WEEK);
		
		while (temp.get(Calendar.DAY_OF_WEEK) != Calendar.FRIDAY) {
			temp.add(Calendar.DATE, Constants.ONE_DAY);
		}

		String nextFriday = String.format(Constants.FORMAT_DATE_STRING,
				temp.get(Calendar.DAY_OF_MONTH), temp.get(Calendar.MONTH)
				+ Constants.ADJUST_MONTH_BY_ONE,
				temp.get(Calendar.YEAR) - Constants.TWENTY_FIRST_CENTURY);

		Logic.parseCommand("clear");

		assertEquals(Logic.parseCommand("+Task one"),
				"Task \"Task one\" has been added");
		assertEquals(Logic.parseCommand("q Task two nxt fri 11am"),
				"Task \"Task two\" has been added");
		assertEquals(Logic.parseCommand("modify 2 e 010115"),
				"Task \"Task one\" end date changed to \"01/01/15\"");
		assertEquals(Logic.parseCommand("modify 1 s nxt fri"),
				"Task \"Task one\" start date changed to " + "\"" + nextFriday + "\"");
		assertEquals(
				Logic.parseCommand("add Buy groceries tomorrow from 12pm to 4pm"),
				"Task \"Buy groceries\" has been added");

		// Delete test case
		assertEquals(Logic.parseCommand("delete 2"),
				"\"Buy groceries\" has been deleted.");

		assertEquals(Logic.parseCommand("-1"), "\"Task one\" has been deleted.");

		assertEquals(Logic.parseCommand("undo"), "Undid successfully.");
		assertEquals(CommandLogic.taskVector.get(1).getDescription(),
				"Task two");
		assertEquals(CommandLogic.taskVector.get(1).getEndDateString(),
				nextFriday);
		assertEquals(Logic.parseCommand("redo"), "Redid successfully.");

	}

	@Test
	public void basicTest2() {
		// Sort, search, today, tomorrow, week,

		Logic.parseCommand("clear");

		assertEquals(Logic.parseCommand("add Task L 260314 280314 5pm"),
				"Task \"Task L\" has been added");
		assertEquals(Logic.parseCommand("add Task A today 0100 2359"),
				"Task \"Task A\" has been added");
		assertEquals(Logic.parseCommand("add Task T 200314 2222"),
				"Task \"Task T\" has been added");
		assertEquals(Logic.parseCommand("add Task E tomorrow 12pm 6pm"),
				"Task \"Task E\" has been added");
		assertEquals(Logic.parseCommand("sort"), "Sorted alphabetically.");
		assertEquals(Logic.parseCommand("sort e"), "Sorted by deadline.");
		assertEquals(Logic.parseCommand("sort s"), "Sorted by start date.");
	}

	@Test
	public void basicTest() {
		Logic.parseCommand("add Finish assignment 260314 280314 5pm");
		Logic.parseCommand("add Study whole day 220314 0100 2359");
		Logic.parseCommand("add Upload softcopy 200314 2222");
		Logic.parseCommand("add Do CS2103 tutorial assignment 280314 12pm 6pm");
		
		try {
			Logic.parseCommand("search assignment");
		} catch (NullPointerException npe) {

		}
		assertEquals(CommandLogic.searchVector.get(0).getDescription(),
				"Finish assignment");
		assertEquals(CommandLogic.searchVector.get(1).getDescription(),
				"Do CS2103 tutorial assignment");
	}

	@Test
	public void exceptionTests1() {
		// Test cases for exceptions that user might input

		Logic.parseCommand("clear");

		//Add exceptions
		assertEquals(Logic.parseCommand("add"), "Please enter a task description.");
		assertEquals(Logic.parseCommand("add nxt fri 12pm"), "Please enter a task description.");
		
		// Empty Exceptions
		assertEquals(Logic.parseCommand("sort"), "There is nothing to sort.");

		// Delete exceptions
		assertEquals(Logic.parseCommand("delete"),
				"Please enter a number to delete the task.");
		// Lower boundary for test case of delete
		assertEquals(Logic.parseCommand("delete -1"),
				"Invalid delete argument: \"-1\"");
		assertEquals(Logic.parseCommand("delete a"),
				"Invalid delete argument: \"a\"");
		// Lower boundary for test case of delete
		assertEquals(Logic.parseCommand("delete 100"), "There is no such task.");

		// Search exceptions
		// There is no search argument (lower input boundary)
		assertEquals(Logic.parseCommand("search "),
				"Please enter the word to search.");

		// Number of tasks that should be in the task vector is 99
		// Boundary for number of tasks is [0, 99]
		// Boundary for input is -1

		// Out of bounds Exceptions (Mark)
		// Upper boundary for test case of mark
		assertEquals(Logic.parseCommand("mark 100"), "There is no such task.");
		// Lower boundary for test case of mark
		assertEquals(Logic.parseCommand("mark -1"),
				"Invalid mark argument: \"-1\"");
		assertEquals(Logic.parseCommand("mark a"),
				"Invalid mark argument: \"a\"");

		// Out of bounds Exceptions (Modify)
		// Lower boundary for test case of modify
		assertEquals(Logic.parseCommand("modify 100"), "There is no such task.");
		// Lower boundary for test case of modify
		assertEquals(Logic.parseCommand("modify -1"),
				"Invalid modify argument: \"-1\"");
		assertEquals(Logic.parseCommand("modify a"),
				"Invalid modify argument: \"a\"");
	}

}
